/*****************************************************************************************/
/* ECSE 426 - Microprocessor - Fall 2009
/* Lab Experiment 3 - UART with SPI
/* UART.C
/* @author: Danny Wu - 260238209 - B.Comp.Eng
/* @author: Han-Sheng Chin - 260209715 - B.Elec.Eng
/* @version: 09.10.17.1508 
/****************************************************************************************/
#include <uart.h>
//control for debug mode
#define DEBUG_MODE FALSE

//general constants
#define TRUE 1
#define FALSE 0
//spi address constants
#define SPI_READ 0x80
#define SPI_WRITE 0x00
#define CSn_PIN 0x01
#define USART1_SIMO   0x02
#define USART1_SOMI   0x04
#define USART1_UCLK   0x08

//initRsUART
void initRsUART(void){
  unsigned int i;  
  do {
    IFG1 &= ~OFIFG;                       // Clear OSCFault flag
    for (i = 0xFF; i > 0; i--);           // Time for flag to set
  } while ((IFG1 & OFIFG) != 0);          // OSCFault flag still set?          
  UCTL0 = CHAR;                         // 8-bit character
  UTCTL0 = SSEL1;                       // UCLK = SMCLK //SSEL0 = ACLOCK
  UBR00 = 0x8A;                         // 8Mhz/57600 - 0x8a
  UBR10 = 0x00;                         // 
  UMCTL0 = 0x00;                        // no modulation
  ME1 |= UTXE0 + URXE0;                 // Enable USART0 TXD
  IE1 |= URXIE0;                        // Enable USART0 RX interrupt
  P3SEL |= 0x30;                        // P3.4,5 = USART0 TXD/RXD
  P3DIR |= 0x10;                        // P3.4 output direction
  _EINT();                              // Enable interrupts   
}//end main

//interrupt for receiving from UART0
void usart0_rx (void) __interrupt[UART0RX_VECTOR] {
  while ((IFG1 & UTXIFG0) == 0);        // USART0 TX buffer ready?
   
  switch( RXBUF0 ){
    case 0x1b: //escape key
        clearScreen();
        break;
    case 0x08: //backspace
        putChar('\b');
        putChar(0x20);
        putChar('\b');
        break;
    default :
        putChar(RXBUF0);                    // RXBUF0 to TXBUF0
        break;
  }//end switch
}//end usart0_rx



//initSpiUART
void initSpiUART(void) {
  volatile unsigned int i;
  P5SEL |= 0x0E;                            // P5.1,2,3 SPI option select
  P5OUT |= 0x0B;                            // 0000 1011
  P5DIR = 0x0B;                             //Reset Slave (high = output)

  U1CTL = CHAR + SYNC + MM + SWRST;         // 8-bit, SPI, Master = Size of data bits(8) + SPI mode + Master Mode
  U1TCTL = CKPL + SSEL1 + STC;              // Polarity, SMCLK, 3-wire
  U1BR0 = 0x02;                             // SPICLK = SMCLK/2
  U1BR1 = 0x00;
  U1MCTL = 0x00;//0x00;//0xEF;
  ME2 |= USPIE1;                            // Module enable
  U1CTL &= ~SWRST;                          // SPI enable
  IE2 |= URXIE1;                            // RX interrupt enable

}// end initSpiUART


void SPI1_rx (void) __interrupt[UART1RX_VECTOR]{
  //TXBUF1 = RXBUF1;                           // RXBUF1 to TXBUF1
  //putChar(RXBUF1);
}//end SPI1_rx


//write single byte to CC2500
void spiWriteReg(char addr, char value) {
    P5OUT &= ~CSn_PIN;                      // --CS enable (set to low)
    while (P5IN&USART1_SOMI);               // Wait for CCxxxx ready
    IFG2 &= ~URXIFG1;                       // Clear flag from first dummy byte
    TXBUF1 = addr;                         // Send address
    while (!(IFG2&URXIFG1));                // Wait for TX to finish
    IFG2 &= ~URXIFG1;                       // Clear flag from first dummy byte
    TXBUF1 = value;                        // Send value
    while (!(IFG2&URXIFG1));                // Wait for end of data TX
    P5OUT |= CSn_PIN;                       // --CS disable (set to high)
}// end spiWriteReg


char spiReadReg(char addr){
  char x;

  P5OUT &= ~CSn_PIN;                        // /CS enable
  while (P5IN&USART1_SOMI);                 // Wait for CCxxxx ready
  IFG2 &= ~URXIFG1;                         // Clear flag set during addr TX
  TXBUF1 = (addr | SPI_READ);              // Send address
  while (!(IFG2&URXIFG1));                  // Wait for TX to finish
  IFG2 &= ~URXIFG1;                         // Clear flag set during last write
  TXBUF1 = 0;                              // Dummy write so we can read data
  while (!(IFG2&URXIFG1));                  // Wait for RX to finish
  x = RXBUF1;                              // Read data
  P5OUT |= CSn_PIN;                       // --CS disable (set to high)

  return x;

}//end spiReadReg

/**
 * Generates a random char
 *   
 */
char getRndChar(void){
  char rnd_element = 33 + rand() % 127;
  return rnd_element;
}//end rand


/**
 * print
 */
void print(char* text){
  int ctr;
  for(ctr=0;text[ctr] != '\0';ctr++)
    putChar(text[ctr]);
}//end print


/**
 * println with a \n before
 */
void println(char* text){
  int ctr;
  putChar('\n');
  for(ctr=0;text[ctr] != '\0';ctr++)
    putChar(text[ctr]);
}//end println

/**
 * putChar on the UART
 */
void putChar(char text){
  if(DEBUG_MODE){
    debug_printf("%d",text);
    debug_printf("%x",text);
  }else{    
    while ((IFG1 & UTXIFG0) == 0);        // USART0 TX buffer ready?
    TXBUF0 = text;                        // RXBUF0 to TXBUF0
  }//end if else
}//end putchar

/**
 * Clears the terminal
 * by shifting the output up.
 */
void clearScreen(void){
  putChar(0xC);
}//end getchar


